import classNames from "classnames";
import React, {
  ChangeEvent,
  createRef,
  FC,
  ReactElement,
  ReactNode,
  useEffect,
  useRef,
  useState,
} from "react";
import useClickOutside from "../../hooks/useClickoutSide";
import useDebounce from "../../hooks/useDebounce";

import styles from "./index.module.less";

interface AutoCompleteProps {
  defaultValue: string;
  onSelect?: (item: string) => void;
  fetchSuggestions: (str: string) => string[] | Promise<string[]>;
  renderOption?: (item: string) => ReactElement;
}
/** 有一个值，数组里有个值，就拿数组相应的index*/

const AutoComplete: FC<AutoCompleteProps> = (props) => {
  const { defaultValue, renderOption, onSelect, fetchSuggestions } = props;
  const ref = useRef<HTMLDivElement>(null);
  const [value, setValue] = useState<string>(defaultValue);
  const [suggestions, setSugestions] = useState<string[]>([]);

  const [linght, setLinght] = useState(-1);

  const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
    const value = e.target.value.trim();
    setValue(value);
  };
  const debouncedValue = useDebounce(value, 300);
  useClickOutside(ref, () => setSugestions([]));
  useEffect(() => {
    if (debouncedValue) {
      const result = fetchSuggestions(debouncedValue);
      if (result instanceof Promise) {
        result.then((res) => {
          setSugestions(res);
        });
      } else {
        setSugestions(result);
      }
    }
  }, [debouncedValue]);

  const [loading, setLoading] = useState(false);

  const triggerSearch = useRef(false);

  // 渲染模板
  const renderTemplate = (str: string) => {
    return renderOption ? renderOption(str) : str;
  };

  const handleSelect = (e: string) => {
    setValue(e);
    setSugestions([]);
  };

  /** 处理键盘事件中的index 的值 （可以更改） */
  const handleLinght = (index: number) => {
    if (index < 0) index = 0;
    if (index >= suggestions.length) {
      index = suggestions.length - 1;
    }
    setLinght(index);
  };

  // 键盘事件
  const handleKeyDown = (key: any) => {
    // console.log(key.keyCode);
    switch (key.keyCode) {
      case 38:
        handleLinght(linght - 1);
        break;
      case 40:
        handleLinght(linght + 1);
        break;
      default:
        break;
    }
  };

  const generalDropdown = () => {
    return (
      <ul>
        {loading && <div>正在加载</div>}
        {suggestions.map((item, index) => {
          const cnames = classNames({
            [styles.bg]: index === linght,
          });
          return (
            <li
              key={index}
              className={cnames}
              onClick={() => handleSelect(item)}
            >
              {renderTemplate(item)}
            </li>
          );
        })}
      </ul>
    );
  };
  return (
    <div ref={ref}>
      <input onKeyDown={handleKeyDown} value={value} onChange={handleChange} />
      {generalDropdown()}
    </div>
  );
};

export default AutoComplete;
